const Koa = require('koa');
const KoaRouter = require('koa-router');
const KoaBodyParse = require('koa-bodyparser');
const KoaViews = require('koa-views');
const KoaStatic = require('koa-static');

const app = new Koa();
const router = new KoaRouter();

app.use(KoaBodyParse());
app.use(KoaStatic(__dirname));
app.use(KoaViews(__dirname, { extension: 'ejs' }));

// C => Controller
router.get('/', async (ctx) => {
    // M => Model
    // 从数据库中，读取数据
    const user = {
        username: 'rui',
        nickname: '杨瑞',
        email: 'lstyr@outlook.com',
    };

    // 检查 cookie 中是否存在 token
    const token = ctx.cookies.token;

    if (token) {
        const { redirect } = ctx.query;
        ctx.redirect(`http://${redirect}?token=${token}`);
        return;
    }

    //

    // 判断显示
    // 有没有权限显示

    // V => View
    await ctx.render('login', { name: '统一认证平台', user });
});

router.post('/', async (ctx) => {
    // 用户名
    const { username, password } = ctx.request.body;

    // 根据用户名，查询数据是否存在该用户

    // 登录
    if (username === 'lstyr' && password === '123456') {
        // 生成 token
        const token = 'passport';

        // 设置 cookie
        ctx.cookies.set('token', token, {
            maxAge: 1000 * 60 * 60 * 24 * 30,
            httpOnly: true,
        });

        // 重定向，并带上 token，然后应用系统发现有 token，会再进行一次 token 校验
        const { redirect } = ctx.query;
        if (redirect) {
            ctx.redirect(`http://${redirect}?token=${token}`);
        } else {
            ctx.body = '<h1>登录成功!</h1>';
        }
    }
});

router.get('/checkToken', async (ctx) => {
    const token = ctx.query.token;
    if (checkToken(token)) {
        ctx.body = {
            code: 200,
            message: '登录成功',
        };
        return;
    }
    ctx.body = {
        code: 401,
        message: 'token 认证失败',
    };
});

app.use(router.routes());
app.listen(3000, () => {
    console.log('认证服务已启动...');
});

/**
 * 校验 token
 * @param {*} token
 */
function checkToken(token) {
    // TODO 从存储系统中查找相应 token 信息，判断 token 的合法性
    if (token) {
        return true;
    }
    return false;
}
